
/*
 * Hlpay-Plus aggregate payment system. Copyright
 * (c) 2022-2023 Hlpay Team Copyright has the right of final interpretation.
 */
package com.hlkj.pay.service.admin.impl;

import java.util.List;
import java.util.Objects;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hlkj.framework.caches.service.RedisTemplateService;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.common.util.string.StrUtils;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.pay.common.constants.AdminRedisConstant;
import com.hlkj.pay.common.constants.AdminUserConstant;
import com.hlkj.pay.dto.admin.OrganizationQueryDto;
import com.hlkj.pay.enums.AdminUserEnum;
import com.hlkj.pay.infrastructure.mapper.admin.OrganizationMapper;
import com.hlkj.pay.infrastructure.model.admin.OrganizationDO;
import com.hlkj.pay.service.CommonSnFilterService;
import com.hlkj.pay.service.admin.IOrganizationService;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.StringUtil;

/**
 * @author HlpayTeam
 * @date 2024/09/08 11:17
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrganizationServiceImpl extends CommonSnFilterService implements IOrganizationService {
    private final OrganizationMapper organizationMapper;

    private final RedisTemplateService redisTemplateService;
    
    @Override
    public PageResult<OrganizationDO> queryOrganizationPage(OrganizationQueryDto organizationQueryDto) {
        // LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest)LocalContext.get();
        // organizationQueryDto.setSn(localAdminUserRequest.getQuerySn());
        return organizationMapper.selectPage(organizationQueryDto,buildWrapper(organizationQueryDto));
    }
    @Override
    public List<OrganizationDO> queryOrganizationList(OrganizationQueryDto organizationQueryDto) {
        // LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest)LocalContext.get();
        // organizationQueryDto.setSn(localAdminUserRequest.getQuerySn());
        return queryList(organizationQueryDto);
    }

    @Override
    public OrganizationDO queryOrganizationDetail(String organizationCode) {
        String redisKey = organizationDataRedisKey(organizationCode);
        String organizationDetail = (String) redisTemplateService.get(redisKey);
        //缓存存在直接返回
        if (StrUtils.isNotBlank(organizationDetail)) {
            // return JsonUtils.parseObject(organizationDetail, OrganizationDO.class);
        }

        //查询数据库
        OrganizationQueryDto organizationQueryDto = new OrganizationQueryDto();
        organizationQueryDto.setOrganizationCode(organizationCode);
        //执行数据库扩展点
        OrganizationDO organizationDO = queryOne(organizationQueryDto);

        if (Objects.nonNull(organizationDO)){
            //回填缓存
            redisTemplateService.set(redisKey, JsonUtils.toJsonStr(organizationDO));
        }
        return organizationDO;
    }

    /**
     * 组织详情 缓存key
     *
     * @param organizationCode 字典编码
     * @return key
     */
    private String organizationDataRedisKey(String organizationCode) {
        return StrUtil.builder().append(AdminRedisConstant.ORGANIZATION_DETAILS_KEY)
                .append(organizationCode).toString();
    }


    @Override
    public void addOrganizationDO(OrganizationDO organizationDO) {
        processSystemOrganizationCode(organizationDO);
        organizationMapper.insert(organizationDO);
    }

    @Override
    public void updateOrganizationDO(OrganizationDO organizationDO,String parentOrganizationCode) {
        if (ObjectUtil.isNotEmpty(organizationDO.getParentOrganizationCode())&&
                !organizationDO.getParentOrganizationCode().equals(parentOrganizationCode)) {
            processSystemOrganizationCode(organizationDO);
        }
        organizationMapper.updateById(organizationDO);
    }
    @Override
    public void delOrganizationDO(Long id) {
        organizationMapper.deleteById(id);
    }
    
    /**
     * processSystemOrganizationCode
     *
     * @param organizationDO
     */
    void processSystemOrganizationCode(OrganizationDO organizationDO) {
        String parentOrganizationCode = organizationDO.getParentOrganizationCode();
        if(!StringUtil.hasText(parentOrganizationCode)){
            OrganizationQueryDto queryDO = new OrganizationQueryDto();
            queryDO.setType(AdminUserEnum.ORGANIZATION_TYPE.HEAD_OFFICE.getCode());
            OrganizationDO maxSystemOrganization = selectLatestOne(queryDO);
            // 之前同一级别不存在
            if (maxSystemOrganization == null) {
                organizationDO.setOrganizationCode(AdminUserConstant.DEFALUT_NEXT_SYSTEM_ORGANIZATION_CODE);
            }
            else {
                String substring = maxSystemOrganization.getOrganizationCode().substring(maxSystemOrganization.getOrganizationCode().length() - 2);
                // 存在 同级别的最大 +01
                Integer integer = Integer.valueOf(substring);
                String organizationCode = String.format("%02d", integer + 1);
                organizationDO.setOrganizationCode(organizationCode);
            }
        }else {
            OrganizationQueryDto queryDO = new OrganizationQueryDto();
            queryDO.setParentOrganizationCode(parentOrganizationCode);
            OrganizationDO maxSystemOrganization = selectLatestOne(queryDO);
            // 之前同一级别不存在
            if (maxSystemOrganization == null) {
                organizationDO.setOrganizationCode(parentOrganizationCode + AdminUserConstant.DEFALUT_NEXT_SYSTEM_ORGANIZATION_CODE);
            }
            else {
                String substring = maxSystemOrganization.getOrganizationCode().substring(maxSystemOrganization.getOrganizationCode().length() - 2);
                // 存在 同级别的最大 +01
                Integer integer = Integer.valueOf(substring);
                String organizationCode = String.format("%02d", integer + 1);
                organizationDO.setOrganizationCode(parentOrganizationCode + organizationCode);
            }
        }
       
    }
    List<OrganizationDO> queryList(OrganizationQueryDto organizationQueryDto) {
        return organizationMapper.selectList(buildWrapper(organizationQueryDto));
    }
    
    OrganizationDO queryOne(OrganizationQueryDto organizationQueryDto) {
        LambdaQueryWrapper<OrganizationDO> lambdaQueryWrapper = buildWrapper(organizationQueryDto);
        lambdaQueryWrapper.orderByDesc(OrganizationDO::getId);
        lambdaQueryWrapper.last(" limit 1");
        return organizationMapper.selectOne(lambdaQueryWrapper);
    }
    OrganizationDO selectLatestOne(OrganizationQueryDto organizationQueryDto) {
        return organizationMapper.selectLatestOne(organizationQueryDto);
    }
    /**
     * 查询条件封装
     *
     * @param organizationQueryDto
     *            查询实体
     */
    LambdaQueryWrapperX<OrganizationDO> buildWrapper(OrganizationQueryDto organizationQueryDto) {
        filterSn(organizationQueryDto);
        LambdaQueryWrapperX<OrganizationDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(OrganizationDO::getParentOrganizationCode, organizationQueryDto.getParentOrganizationCode());
        queryWrapper.eqIfPresent(OrganizationDO::getOrganizationCode, organizationQueryDto.getOrganizationCode());
        queryWrapper.inIfPresent(OrganizationDO::getOrganizationCode, organizationQueryDto.getOrganizationCodes());
        queryWrapper.eqIfPresent(OrganizationDO::getType, organizationQueryDto.getType());
        queryWrapper.eqIfPresent(OrganizationDO::getSn, organizationQueryDto.getSn());
        queryWrapper.inIfPresent(OrganizationDO::getSn, organizationQueryDto.getSnList());
        queryWrapper.eqIfPresent(OrganizationDO::getSysType, organizationQueryDto.getSysType());
        queryWrapper.likeIfPresent(OrganizationDO::getOrganizationName, organizationQueryDto.getLikeOrganizationName());
        queryWrapper.likeRight(StringUtil.hasText(organizationQueryDto.getLikeOrganizationCode()),OrganizationDO::getOrganizationCode, organizationQueryDto.getLikeOrganizationCode());
        return queryWrapper;
    }
}
